package main

import "fmt"

func main() {
	/*
		1.多值赋值的两种格式：
			（1）右边是一个返回多值的表达式，可以是返回多值的函数调用，也可以是 range 对 map, slice 等函数的操作，还可以是类型断言
				//函数调用
				x, y = f()

				//range 表达式
				for k, v := range map {
				}

				//type assertion(类型断言)
				v, ok := i.(xxxx)

			（2）赋值的左边操作数和右边的单一返回值表达式的个数一样，逐个从左向右依次对左边的操作数赋值
				x, y, z := a, b, c

			注：多值赋值语句中每个变量后面不能都带上类型
				eg: var x int, y string = 1, "tt" //不允许

		2.多值赋值的语义：
			（1）对左侧操作数中的表达式、索引值进行计算和确定
				首先，确定左侧的操作数的地址
				然后，对右侧的赋值表达式进行计算
					如果发现右侧的表达计算式引用了左侧的变量，则创建临时变量进行值拷贝
				最后，完成计算
			（2）从左到右的顺序依次赋值
	*/
	x := []int{1, 2, 3}
	i := 0
	i, x[i] = 1, 2 //set i = 1, x[0] = 2
	fmt.Println(1, x)

	x = []int{1, 2, 3}
	i = 0
	x[i], i = 2, 1 //set x[0] = 2, i = 1
	fmt.Println(i, x)

	x = []int{1, 2, 3}
	i = 0
	x[i], i = 2, x[i] //set tmp = x[0], x[0] = 2, i = tmp = 1
	fmt.Println(i, x)

	x[0], x[0] = 1, 2 //set x[0] = 1, x[0] = 2 (so x[0] = 2 at end)
	fmt.Println(x[0])
}
